package com.tomorrow.payments_hodgepodge.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.stripe.Stripe;
import com.stripe.exception.ApiConnectionException;
import com.stripe.exception.StripeException;
import com.stripe.model.*;
import com.stripe.param.*;
import com.tomorrow.payments_hodgepodge.service.StripeService;
import com.tomorrow.payments_hodgepodge.util.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Tomorrow
 * @date 2020/11/13 14:58
 */
@Service
@Slf4j
public class StripeServiceImpl implements StripeService {
    @Value("${project.STRIPE.PUBLIC_KEY}")
    public String publicKey;
    @Value("${project.STRIPE.PRIVATE_KEY}")
    public String privateKey;
    @Value("${project.STRIPE.CURRENCY}")
    public String currency;

    @Override
    public CommonResult createSetupIntent() {
        Stripe.apiKey = privateKey;

        try {
            CustomerCreateParams params =
                    CustomerCreateParams.builder()
                            .build();

            Customer customer = Customer.create(params);

            Map<String, Object> paramsSetupIntent = new HashMap<>();
            paramsSetupIntent.put("customer", customer.getId());
            SetupIntent setupIntent = SetupIntent.create(paramsSetupIntent);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("publicKey", publicKey);
            jsonObject.put("customerId", setupIntent.getCustomer());
            jsonObject.put("clientSecret", setupIntent.getClientSecret());
            return CommonResult.success("SUCCESS", jsonObject);
        } catch (ApiConnectionException e) {
            log.error("Stripe 创建SetupIntent异常: " + e);
            return CommonResult.fail(500, "NetworkTimeout");
        } catch (StripeException e) {
            log.error("Stripe 创建SetupIntent异常: " + e);
            return CommonResult.failMessage(500, e.getStripeError().getCode(), e.getStripeError().getMessage());
        }
    }

    @Override
    public CommonResult getBankCardInformation(String customerId) {
        Stripe.apiKey = privateKey;

        try {
            PaymentMethodListParams params =
                    PaymentMethodListParams.builder()
                            .setCustomer(customerId)
                            .setType(PaymentMethodListParams.Type.CARD)
                            .build();

            PaymentMethodCollection paymentMethods = PaymentMethod.list(params);
            PaymentMethod paymentMethod = paymentMethods.getData().get(0);
            // 获取到银行卡信息
            JSONObject jsonObject = new JSONObject();
            // 银行卡类型
            jsonObject.put("brand", paymentMethod.getCard().getBrand());
            // 银行卡月份
            jsonObject.put("expMonth", paymentMethod.getCard().getExpMonth());
            // 银行卡年份
            jsonObject.put("expYear", paymentMethod.getCard().getExpYear());
            // 银行卡后四位
            jsonObject.put("last4", paymentMethod.getCard().getLast4());
            // 客户的ID
            jsonObject.put("customerId", paymentMethod.getCustomer());
            // paymentMethodId 对象的唯一标识符
            jsonObject.put("paymentMethodId", paymentMethod.getId());
            return CommonResult.success("SUCCESS", jsonObject);
        } catch (StripeException e) {
            log.error("Stripe 检索PaymentMethod对象数据异常: " + e);
            return CommonResult.failMessage(500, e.getStripeError().getCode(), e.getStripeError().getMessage());
        }
    }

    @Override
    public CommonResult payOrder(String paymentMethodId, String customerId) {
        Stripe.apiKey = privateKey;

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("amount", 6200);
            params.put("currency", "USD");
            params.put("customer", customerId);
            params.put("payment_method", paymentMethodId);
            params.put("confirm", true);

            PaymentIntent paymentIntent = PaymentIntent.create(params);
            System.out.println(paymentIntent);
            if (paymentIntent != null && "succeeded".equals(paymentIntent.getStatus())) {
                return CommonResult.success("SUCCESS", paymentIntent.getId());
            } else {
                return CommonResult.fail(500, "Pay.payError");
            }
        } catch (StripeException e) {
            log.error("Stripe 支付异常: " + e);
            return CommonResult.failMessage(500, e.getStripeError().getCode(), e.getStripeError().getMessage());
        }
    }

    @Override
    public CommonResult stripeAuthorize(String orderNo) {
        Stripe.apiKey = privateKey;

        try {
            List<Object> paymentMethodTypes = new ArrayList<>();
            paymentMethodTypes.add("card");
            Map<String, Object> params = new HashMap<>();
            params.put("amount", 9000);
            params.put("currency", currency);
            params.put("customer", "cus_IOuwqJFe3TuDDB");
            params.put("payment_method", "pm_1Ho76qJzV0Wnr0fF0EVOz2tC");
            params.put("capture_method", PaymentIntentCreateParams.CaptureMethod.MANUAL);
            params.put(
                    "payment_method_types",
                    paymentMethodTypes
            );

            // 创建授权订单
            PaymentIntent paymentIntent = PaymentIntent.create(params);

            // 确认付款意向
            PaymentIntent payment =
                    PaymentIntent.retrieve(
                            paymentIntent.getId()
                    );
            PaymentIntent updatedPaymentIntent = payment.confirm();

            return CommonResult.success("SUCCESS", updatedPaymentIntent.getId());
        } catch (ApiConnectionException e) {
            log.error("Stripe 授权流程异常: " + e);
            return CommonResult.fail(500, "NetworkTimeout");
        } catch (StripeException e) {
            log.error("Stripe 授权流程异常: " + e);
            return CommonResult.failMessage(500, e.getStripeError().getCode(), e.getStripeError().getMessage());
        }
    }

    @Override
    public CommonResult stripeCapture(String token) {
        Stripe.apiKey = privateKey;

        try {
            PaymentIntent paymentIntent = PaymentIntent.retrieve(token);

            PaymentIntentCaptureParams params =
                    PaymentIntentCaptureParams.builder()
                            .setAmountToCapture(9000L)
                            .build();

            PaymentIntent capture = paymentIntent.capture(params);
            return CommonResult.success("SUCCESS", capture.getCharges().getData().get(0).getId());
        } catch (ApiConnectionException e) {
            log.error("Stripe 捕获流程异常: " + e);
            return CommonResult.fail(500, "NetworkTimeout");
        } catch (StripeException e) {
            log.error("Stripe 捕获流程异常: " + e);
            return CommonResult.failMessage(500, e.getStripeError().getCode(), e.getStripeError().getMessage());
        }
    }
}
